﻿using System;
using System.Security.Cryptography;
using System.IO;
using Ice.Toolkit.Utility;

namespace Ice.Toolkit.Utility
{
    /// <summary>
    /// DES加密算法
    /// </summary>
    public class DES
    {
        private static DES _instance = new DES();
        /// <summary>
        /// 当前实例
        /// </summary>
        public static DES Instance
        {
            get
            {
                return _instance;
            }
        }

        private readonly byte[] KEY;
        private readonly byte[] IV;
        /// <summary>
        /// 默认构造函数 默认KEY=qikancom
        /// </summary>
        public DES() : this(new byte[] { 0x71, 0x69, 0x6b, 0x61, 0x6E, 0x63, 0x6F, 0x6D }) { }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="keyString">密钥,长度必须为8位</param>
        public DES(string keyString) : this(StringHelper.StrEncoding.StrToBytes(keyString)) { }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="key">密钥,数组长度必须为8位</param>
        public DES(byte[] key) : this(key, new byte[] { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF }) { }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="key">密钥,数组长度必须为8位</param>
        /// <param name="iv">向量,数组长度必须为8位</param>
        public DES(byte[] key, byte[] iv)
        {
            KEY = key;
            IV = iv;
        }
        /// <summary>
        /// 加密字符串
        /// </summary>
        /// <param name="input">要加密的字符串</param>
        /// <returns>加密后的字符串</returns>
        public string Encrypt(string input)
        {
            DESCryptoServiceProvider des = new DESCryptoServiceProvider();

            byte[] i = StringHelper.StrEncoding.StrToBytes(input);

            using (MemoryStream stream = new MemoryStream())
            {
                ICryptoTransform cryptoTransorm = des.CreateEncryptor(KEY, IV);

                using (CryptoStream cs = new CryptoStream(stream, cryptoTransorm, CryptoStreamMode.Write))
                {
                    cs.Write(i, 0, i.Length);
                    cs.FlushFinalBlock();
                }

                return Convert.ToBase64String(stream.ToArray());
            }
        }
        /// <summary>
        /// 解密字符串
        /// </summary>
        /// <param name="input">要解密字符串的字符串</param>
        /// <returns>解密字符串后的字符串</returns>
        public string Decrypt(string input)
        {
            DESCryptoServiceProvider des = new DESCryptoServiceProvider();

            byte[] i = Convert.FromBase64String(input);

            using (MemoryStream stream = new MemoryStream())
            {
                ICryptoTransform cryptoTransorm = des.CreateDecryptor(KEY, IV);

                using (CryptoStream cs = new CryptoStream(stream, cryptoTransorm, CryptoStreamMode.Write))
                {
                    cs.Write(i, 0, i.Length);
                    cs.FlushFinalBlock();
                }

                return StringHelper.StrEncoding.BytesToStr(stream.ToArray());
            }
        }
    }
}
